package com.dankegongyu.lib.common.widget.dropdown;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import com.dankegongyu.lib.common.R;

/**
 * https://github.com/baiiu/DropDownMenu
 * 
 * @author WuPuquan
 * @version 1.0
 * @since 2017/9/27 11:10
 */

public class DropDownMenu extends RelativeLayout implements DropDownMenuTab.OnTabItemClickListener {

    private static final int ANIM_DURATION = 250;

    // 内容布局
//    private int mContentViewLayoutId;
    // tab高度
    private int mDropDownMenuTabHeight = 50;
    private int mTopLineHeight;
    private int mBottomLineHeight;
    private int mTopLineColor;
    private int mBottomLineColor;

    private DropDownMenuTab mDropDownMenuTab;
    private FrameLayout mFrameContainer;

    private View mCurrentView;

    private Animation dismissAnimation;
    private Animation occurAnimation;
    private Animation alphaDismissAnimation;
    private Animation alphaOccurAnimation;

    private DropDownMenuAdapter mDropDownMenuAdapter;
    // 点击tab内容布局执行动画期间再点击不做处理，否则会失效
    private boolean isAnimationExecuting;
    private OnMenuListener mOnMenuListener;

    public DropDownMenu(Context context, AttributeSet attrs) {
        super(context, attrs);

        mDropDownMenuTabHeight = DropDownMenuUtil.dp2px(context, mDropDownMenuTabHeight);

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DropDownMenu);
        try {
//            mContentViewLayoutId = ta.getResourceId(R.styleable.DropDownMenu_ddm_contentViewLayoutId, -1);
            mDropDownMenuTabHeight = ta.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_tabHeight, mDropDownMenuTabHeight);
            mTopLineHeight = ta.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_topLineHeight, -1);
            mBottomLineHeight = ta.getDimensionPixelSize(R.styleable.DropDownMenu_ddm_bottomLineHeight, -1);
            mTopLineColor = ta.getColor(R.styleable.DropDownMenu_ddm_topLineColor, -1);
            mBottomLineColor = ta.getColor(R.styleable.DropDownMenu_ddm_bottomLineColor, -1);
        } finally {
            ta.recycle();
        }

//        if (mContentViewLayoutId == -1) {
//            throw new IllegalArgumentException("ContentViewLayoutId cannot be null!");
//        }

        setContentView();
    }

//    @Override
//    protected void onFinishInflate() {
//        super.onFinishInflate();
//
//        setContentView();
//    }

    private void setContentView() {
        removeAllViews();

        // 添加tab
        mDropDownMenuTab = new DropDownMenuTab(getContext());
        mDropDownMenuTab.setId(R.id.dropDownMenuTab);
        mDropDownMenuTab.setTopLineHeight(mTopLineHeight);
        mDropDownMenuTab.setBottomLineHeight(mBottomLineHeight);
        mDropDownMenuTab.setTopLineColor(mTopLineColor);
        mDropDownMenuTab.setBottomLineColor(mBottomLineColor);
        addView(mDropDownMenuTab, LayoutParams.MATCH_PARENT, mDropDownMenuTabHeight);

        RelativeLayout.LayoutParams lpFrame = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        lpFrame.addRule(BELOW, R.id.dropDownMenuTab);

        // contentView内容界面
//        View contentView = View.inflate(getContext(), mContentViewLayoutId, null);
//        addView(contentView, lpFrame);

        // 添加选中tab时展示页面
        mFrameContainer = new FrameLayout(getContext());
        mFrameContainer.setBackgroundColor(0x7f000000); // 黑色半透明
        addView(mFrameContainer, lpFrame);
        mFrameContainer.setVisibility(View.GONE);

        initListeners();
        initAnimation();
    }

    private void initListeners() {
        mFrameContainer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isShowing()) {
                    close();
                }
            }
        });
        mDropDownMenuTab.setOnTabItemClickListener(this);
    }

    private void initAnimation() {
        occurAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.dropdown_top_in);
        occurAnimation.setDuration(ANIM_DURATION);
        occurAnimation.setAnimationListener(animationOccurListener);

        dismissAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.dropdown_top_out);
        dismissAnimation.setDuration(ANIM_DURATION);
        dismissAnimation.setAnimationListener(animationDismissListener);

        alphaDismissAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.dropdown_alpha_to_zero);
        alphaDismissAnimation.setDuration(ANIM_DURATION);
        alphaDismissAnimation.setAnimationListener(animationDismissListener);

        alphaOccurAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.dropdown_alpha_to_one);
        alphaOccurAnimation.setDuration(ANIM_DURATION);
        alphaOccurAnimation.setAnimationListener(animationOccurListener);
    }

    private Animation.AnimationListener animationOccurListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            isAnimationExecuting = true;
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            isAnimationExecuting = false;
            if (mOnMenuListener != null) {
                mOnMenuListener.onMenuContentVisibleChanged(true);
            }
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };

    private Animation.AnimationListener animationDismissListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            isAnimationExecuting = true;
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            isAnimationExecuting = false;
            if (mCurrentView != null) {
                mCurrentView.setVisibility(View.GONE);
            }
            mFrameContainer.setVisibility(GONE);
            if (mOnMenuListener != null) {
                mOnMenuListener.onMenuContentVisibleChanged(false);
            }
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };

    public boolean isShowing() {
        verifyContainer();
        return mFrameContainer.isShown();
    }

    private void verifyContainer() {
        if (mFrameContainer == null) {
            throw new IllegalStateException("you must initiation setContentView() before");
        }
    }

    public void close() {
        if (isClosed()) {
            return;
        }

        mFrameContainer.startAnimation(alphaDismissAnimation);
        mDropDownMenuTab.reset();

        if (mCurrentView != null) {
            mCurrentView.startAnimation(dismissAnimation);
        }
    }

    public void closeWithoutAnimation() {
        if (mCurrentView != null) {
            mCurrentView.setVisibility(View.GONE);
        }
        mFrameContainer.setVisibility(GONE);
        if (mOnMenuListener != null) {
            mOnMenuListener.onMenuContentVisibleChanged(false);
        }
        mDropDownMenuTab.reset();
    }

    public boolean isClosed() {
        return !isShowing();
    }

    @Override
    public void onTabItemClick(View v, int position, boolean selected) {
        if (mOnMenuListener != null) {
            mOnMenuListener.onMenuTabClick(position, mFrameContainer.isShown());
        }
        if (isAnimationExecuting) {
            return;
        }
        if (selected) {
            close();
        } else {
            mCurrentView = mFrameContainer.getChildAt(position);
            if (mCurrentView == null) {
                return;
            }

            int currentSelectedPosition = mDropDownMenuTab.getCurrentSelectedPosition();
            if (currentSelectedPosition != -1) {
                View child = mFrameContainer.getChildAt(currentSelectedPosition);
                if (child != null) {
                    child.setVisibility(View.GONE);
                }
            }
            View child = mFrameContainer.getChildAt(position);
            if (child != null) {
                child.setVisibility(View.VISIBLE);
            }
            mDropDownMenuTab.setTabSelected(position);

            if (isClosed()) {
                mFrameContainer.setVisibility(VISIBLE);
                mFrameContainer.startAnimation(alphaOccurAnimation);
                // 可移出去,进行每次展出
                mCurrentView.startAnimation(occurAnimation);
            }
        }
    }

    public void setDropDownMenuAdapter(DropDownMenuAdapter dropDownMenuAdapter) {
        verifyContainer();

        mDropDownMenuAdapter = dropDownMenuAdapter;
        verifyMenuAdapter();

        mDropDownMenuTab.setTabs(mDropDownMenuAdapter);

        addChildView();
    }

    private void verifyMenuAdapter() {
        if (mDropDownMenuAdapter == null) {
            throw new IllegalStateException("the menuAdapter is null");
        }
    }

    private void addChildView() {
        removeAllChild();
        for (int i = 0; i < mDropDownMenuAdapter.getMenuCount(); i++) {
            addChildView(i, findViewAtPosition(i), mDropDownMenuAdapter.getBottomMargin(i));
        }
    }

    public View findViewAtPosition(int position) {
        verifyContainer();

        View view = mFrameContainer.getChildAt(position);
        if (view == null) {
            view = mDropDownMenuAdapter.getContentView(position, mFrameContainer);
        }
        return view;
    }

    private void addChildView(int position, View view, int bottomMargin) {
        verifyContainer();
        if (view == null || position > mDropDownMenuAdapter.getMenuCount() || position < 0) {
            throw new IllegalStateException("the view at " + position + " cannot be null");
        }

        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        params.bottomMargin = bottomMargin;//添加距离底部高度
        mFrameContainer.addView(view, position, params);
        view.setVisibility(GONE);
    }

    private void removeAllChild() {
        mFrameContainer.removeAllViews();
    }

    public DropDownMenuTab getDropDownMenuTab() {
        return mDropDownMenuTab;
    }

    public int getTabCount() {
        return mDropDownMenuTab == null ? 0 : mDropDownMenuTab.getTabCount();
    }

    public interface OnMenuListener {
        /**
         * tab点击监听
         *
         * @param position             点击项
         * @param isMenuContentShowing 当前menu内容是否为显示状态
         */
        void onMenuTabClick(int position, boolean isMenuContentShowing);

        void onMenuContentVisibleChanged(boolean visible);
    }

    public void setOnMenuChangedListener(OnMenuListener onMenuListener) {
        this.mOnMenuListener = onMenuListener;
    }

    /**
     * 改变主题风格
     */
    public void updateTheme(DropDownMenuTheme theme) {
        if (theme != null) {
            mDropDownMenuTab.updateTheme(theme);
        }
    }
}
